Skip to content

Add SetProg templates - #38

Merged
JulienCalbert merged 7 commits into
masterfrom
bl/setprog-template
Oct 12, 2026
Merged

JulienCalbert merged 7 commits into
masterfrom
bl/setprog-template

Conversation

@blegat

@blegat blegat commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

This adds a template whose node functions are the sets of SetProg. For a homogeneous node function of degree d, the stability edge inequality V_dst(A x) ≤ γᵈ V_src(x) is the set inclusion (A / γ) S_src ⊆ S_dst, and this template hands that inclusion to SetProg.

What it adds over the existing templates is the piecewise semi-ellipsoid, a function
that is quadratic on each cone of a fixed partition. SetProg also covers the families PCC
already has, which is how the template is checked.

using SetProg
P = polyhedron(hrep([HalfSpace(a, 6.0) for a in normals]), lib)   # the partition
template = PCC.SetProgTemplate(Ellipsoid(symmetric = true, piecewise = P))
certificate = PCC.jsr_bound(template, graph, problem; optimizer)

Supported set variables

variable V_s(x) Degree Same family as
Ellipsoid(symmetric = true) x' Q_s x 2 QuadraticTemplate
PolySet(symmetric = true, degree = 2d, variables = x) a polynomial p_s(x) 2d SumOfSquaresTemplate(d, x)
Polytope(symmetric = true, piecewise = P) a_{s,i}' x on the ith cone 1 ConicPolyhedralTemplate on the same cones
Ellipsoid(symmetric = true, piecewise = P) x' Q_{s,i} x on the ith cone 2 new

Pass one variable to share it across nodes, or a vector with one per node to give each
node its own partition. With one per node, reindex gives each node of a lifted graph
the variable of its origin, like the polyhedral templates.

Benchmarks

The system is the one from test/templates/sum_of_squares.jl: a rotation and a shear, both
scaled by 0.69. Every rate is an upper bound on the joint spectral radius from
jsr_bound with Clarabel and rtol = 1e-4. The joint spectral radius is at least 0.69,
the spectral radius of each mode.

One node (two self-loops):

Template Rate
QuadraticTemplate 0.9758
SetProgTemplate(Ellipsoid(symmetric = true)) 0.9758
SumOfSquaresTemplate(2, x) 0.9122
SetProgTemplate(PolySet(symmetric = true, degree = 4, variables = x)) 0.9122
ConicPolyhedralTemplate([planar_conic_partition(1)]) 1.0113
SetProgTemplate(Polytope(symmetric = true, piecewise = octagon)) 1.0113
SetProgTemplate(Ellipsoid(symmetric = true, piecewise = square)), 4 pieces 0.9758
SetProgTemplate(Ellipsoid(symmetric = true, piecewise = octagon)), 8 pieces 0.9362

de_bruijn(1, 2) (two nodes):

Template Rate
QuadraticTemplate 0.9246
SetProgTemplate, square partition at node 1 and octagon at node 2 0.9243
  • Cross-checks: each of the three families PCC already has gives the same rate as its
    existing template.
  • Partitions: the octagon's vertices are on the rays ±(1, 0), ±(1, 1), ±(0, 1) and
    ±(−1, 1). Its facet cones are exactly those of planar_conic_partition(1), which is
    what makes the polytope comparison meaningful.
  • Piecewise semi-ellipsoids: with 8 pieces the bound drops from 0.9758 to 0.9362.
    With 4 pieces on this system, the optimum has all pieces equal to the ellipsoid.

How it is built

  • Edges: add_domination! folds the scale into the map, (map / γ) * S_src ⊆ S_dst
    with γ = scale^(1/d). A nonzero margin and a scale that is a JuMP expression both
    throw an ArgumentError, as the interface asks.
  • Normalization: add_normalization! constrains S ⊆ unit, i.e. V(x) ≥ ‖x‖₂ᵈ, or
    V ≥ the gauge of P for a polytope. The unit set is written in the variable's own
    family. The edge conditions are homogeneous, so this fixes the scale and excludes
    V ≡ 0 without excluding any certificate.
  • Space: everything is modeled in SetProg's primal space, where a set is represented
    by its gauge function. A constant polynomial or piecewise superset has no dual
    representation.
  • Fitted functions: SetProgFunction is callable. On a piecewise set it evaluates the
    piece containing x, and the function is continuous, so a boundary point can use
    either neighbour.

Limitations

  • Stability only, like the other non-quadratic templates.
  • No domination_slack, the same as SumOfSquaresTemplate. So edge_slacks,
    tight_edges and refine do not work with this template yet.
  • No closures declared, so order_witness only uses the template-free simulation
    map. Both rows are in the graph-layer table of What works with what.
  • Partitions need exact facets. Rounding noise in the facet normals, like the 1e-16
    of a cos(π/2), can make the solver report ALMOST_OPTIMAL for a point that violates
    the edge inequalities by a lot. In a SetProg prototype with Hypatia, a 45°-rotated
    square with noisy normals "certified" 0.62, below the 0.69 lower bound; with the
    normals rounded it gives 0.9758. PCC counts ALMOST_OPTIMAL as feasible, so the
    docstring warns about it and the tests use exact partitions. The cause is in
    SetProg/Polyhedra's handling of the pieces and is left for a separate fix.

blegat added 3 commits October 8, 2026 11:58
SetProgTemplate uses the sets of SetProg as node functions: ellipsoids,
polynomial sets, and what the other templates do not have, piecewise
semi-ellipsoids and piecewise polytopes. Stability only, like the
sum-of-squares template. Needs SetProg with support for constant
supersets, blegat/SetProg.jl branch bl/constant_superset.
@codecov

codecov Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.33333% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.82%. Comparing base (6e52f19) to head (7fafe82).

Files with missing lines Patch % Lines
ext/PathCompleteCertificatesSetProgExt.jl 97.10% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #38      +/-   ##
==========================================
+ Coverage   96.72%   96.82%   +0.09%     
==========================================
  Files          47       49       +2     
  Lines        1404     1479      +75     
==========================================
+ Hits         1358     1432      +74     
- Misses         46       47       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@JulienCalbert
JulienCalbert merged commit c07e934 into master Oct 12, 2026
9 checks passed
@JulienCalbert
JulienCalbert deleted the bl/setprog-template branch October 12, 2026 08:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants